package com.hzcc.hzccblog.config;

import com.hzcc.hzccblog.shiro.CORSAuthenticationFilter;
import com.hzcc.hzccblog.shiro.ShiroFilter;
import com.hzcc.hzccblog.shiro.ShiroSessionManager;
import com.hzcc.hzccblog.shiro.UserRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author 早睡蛋
 * @Date 2022/6/6 19:46:37
 * @Desc:Shiro配置类
 */
@Configuration
public class ShiroConfig {


    /**
     * 自定义的 shiro session 缓存管理器，用于跨域等情况下使用 token 进行验证，不依赖于sessionId
     * @return
     */
    @Bean
    public SessionManager sessionManager(){
        // 将我们继承后重写的shiro session 注册
        ShiroSessionManager shiroSession = new ShiroSessionManager();
        // 如果后续考虑多tomcat部署应用，可以使用shiro-redis开源插件来做session的控制，或者nginx的负载均衡
        shiroSession.setSessionDAO(new EnterpriseCacheSessionDAO());
        return shiroSession;
    }

    /**
     * anon:无权限即可访问
     * authc:需要认证才能访问
     */
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/api/login/loginUrl");

        Map<String, String> filterChainDefinitionMap = ShiroFilter.linkedHashMap();
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        // 自定义拦截器限制并发人数
        LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();
        // 统计登录人数:限制同一帐号同时在线的个数
        //filtersMap.put("kickout", kickoutSessionControlFilter());
        // 自定义跨域前后端分离验证过滤器-自定义token情况
        filtersMap.put("corsAuthenticationFilter", new CORSAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);

        return shiroFilterFactoryBean;
    }


    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(userRealm());
        defaultWebSecurityManager.setSessionManager(sessionManager());
        return defaultWebSecurityManager;
    }

    @Bean
    public UserRealm userRealm() {
        UserRealm userRealm = new UserRealm();
        return userRealm;
    }

}
